package com.ys.p1.method;

import java.util.Scanner;

/**
 * @author CodeYang
 * @Description 万年历方法抽离:
 * @Date 2020/12/8 16:44
 */
public class 万年历练习 {


    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // 1获得合法的年 与 月
        int year = getCheckYear(input);
        int month = getCheckMonth(input);

        // 定义用于获取, 从1900年到 (year)今年之前的总天数:
        int yearDays = sumFrom19900ToLastYearDays(year);
        //获得1月到month月之间的天数(不包括当前月)  从1月开始到month
        int sumPastMonthDay = sumFromJanuaryToLastMonth(month, year);

        // 获得当前年,当前月的总天数: 也就是当月总天数
        int sumNowMonthDays = sumNowMonthDays(month, year);
        // 画布局:
        printLayoutView(sumNowMonthDays, week(yearDays, sumPastMonthDay));

    }

    /**
     * 检查年份是否合法
     * 必须大于1900年
     *
     * @param input Scanner 扫描类
     * @return 年份
     */
    static int getCheckYear(Scanner input) {
        int year = 0;
        while (true) {
            System.out.print("请输入年：");
            year = input.nextInt();
            if (year < 1900) {
                System.out.println("您输入年份有误!,请重新输入");
            } else {
                return year;
            }
        }
    }

    static int getCheckMonth(Scanner input) {
        int month = 0;
        while (true) {
            System.out.print("请输入月：");
            month = input.nextInt();
            if (month < 1 || month > 12) {
                System.out.println("您输入月份有误!,请重新输入");
            } else {
                return month;
            }
        }
    }

    /**
     * 画布局
     */
    static void printLayoutView(int sumNowMonthDays, int temp) {
        // 画控制台布局
        System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
        // 当前月的第一天是星期几,那么就要载前面打印几个空格 之前
        int weekBeforeTemp = temp;
        // 1先画空格
        for (int i = 0; i < weekBeforeTemp; i++) {
            System.out.print("\t\t");
        }
        // 展示当前月的天数,也就是画 当年月天数的布局
        // 4.5 展示当前月的天数
        for (int i = 1; i <= sumNowMonthDays; i++) {
            System.out.print(i + "\t\t");
            // 当这个星期要结束了,就换行
            if ((weekBeforeTemp + i) % 7 == 0) {
                System.out.println();
            }
        }
    }

    /**
     * 计算当月的第一天是星期几:
     * 1%7 =1 星期1
     * ( year的天数+month的天数+1(因为历史规定从1900年1月1日是星期1 ,但是我们的1月1日sumDay却是从0开始计数的所以这里+1) ) % 7 =星期几
     * (yDays+mDays+1)%7 代表这天星期几
     * 还有个变形--->今天星期几
     * ------当前(当前月的第一天)是星期几,那么就可以操作,这个月前面应该有几个空格.
     *
     * @param yearDays        年的总天数(1900-目标年)
     * @param sumPastMonthDay 月总天数(1月1日到-目标月)
     * @return int  星期几
     */
    static int week(int yearDays, int sumPastMonthDay) {
        //(yDays+mDays+1)%7  节约变量 ,也可以直接返回
        int allDays = yearDays + sumPastMonthDay;
        //   System.out.println("星期几:"+(allDays+1 )%7);  建议+1 因年的总天数还是从0开始的
        return (allDays + 1) % 7;
    }

    /**
     * 根据输入月份返回当月的总天数
     * 获得当前年,当前月的总天数: 也就是当月总天数
     *
     * @param month int  输入月
     * @param year  int   输入年
     * @return int 返回当月天数
     */
    static int sumNowMonthDays(int month, int year) {
        switch (month) {
            case 2:
                return isCheckLeapYear(year) ? 29 : 28;
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            default:
                return 30;
        }
    }

    /**
     * 计算今(year)年从1月1日到上个月的月末的总天数 不包括本月
     * 获得1月到month月之间的天数(不包括当前月)  从1月开始到month
     *
     * @param month int 当前月
     * @param year  int 当前年
     * @return int 总天数--(从1月到-year年month月之间的总天数)
     */
    static int sumFromJanuaryToLastMonth(int month, int year) {
        int sumDays = 0;
        for (int i = 1; i < month; i++) {
            sumDays += sumNowMonthDays(i, year);
        }
        return sumDays;
    }

    /**
     * 计算从1900年到去年12月31日的总天数
     *
     * @param year int类型，当前年份
     * @return int类型，返回总天数
     */
    static int sumFrom19900ToLastYearDays(int year) {
        int sumDays = 0;
        for (int i = 1900; i < year; i++) {
            return sumDays += isCheckLeapYear(i) ? 366 : 365;
        }
        return sumDays;
    }

    /**
     * 检查判断平年,闰年
     *
     * @param year
     * @return 平年发回false 闰年返回true
     */
    public static boolean isCheckLeapYear(int year) {
        // 判断一下 平年与闰年的天数变化:
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return true;
        }
        return false;
    }


}
